package com.futvan.z.framework.util;

import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.CompactWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class XmlUtil {

	/**
	 * 对象转XML报文
	 * 
	 * @param obj
	 * @param alias
	 * @return
	 */
	public static String ObjectToXml(Object obj,String class_name,java.lang.Class class_info) {
		String returnvalue = null;
		XStream xstream = new XStream(new DomDriver());
		xstream.alias(class_name, class_info);
		returnvalue = xstream.toXML(obj);
		returnvalue = returnvalue.replace("&lt;", "<");
		returnvalue = returnvalue.replace("&gt;", ">");
		return returnvalue;
	}

	/**
	 * 对象转XML报文
	 * 
	 * @param obj
	 * @param alias
	 * @return
	 */
	public static String ObjectToXml(Object obj,HashMap<String,java.lang.Class> alias) {
		String returnvalue = null;
		XStream xstream = new XStream(new DomDriver());
		if (alias != null) {
			for (String key : alias.keySet()) {
				xstream.alias(key, alias.get(key));
			}
		}
		returnvalue = xstream.toXML(obj);
		returnvalue = returnvalue.replace("&lt;", "<");
		returnvalue = returnvalue.replace("&gt;", ">");
		returnvalue = returnvalue.replace("&quot;", "\"");
		return returnvalue;
	}

	/**
	 * 对象转XML报文
	 * 
	 * @param obj
	 * @param alias
	 * @return
	 */
	public static String ObjectToXml(Object obj,HashMap<String, java.lang.Class> alias,HashMap<String, java.lang.Class> useAttribute) {
		String returnvalue = "";
		XStream xstream = new XStream(new DomDriver());
		if (alias != null) {
			for (String key : alias.keySet()) {
				xstream.alias(key, alias.get(key));
			}
		}

		if (useAttribute != null) {
			for (String key : useAttribute.keySet()) {
				xstream.useAttributeFor(useAttribute.get(key), key);
			}
		}
		returnvalue = xstream.toXML(obj);
		returnvalue = returnvalue.replace("&lt;", "<");
		returnvalue = returnvalue.replace("&gt;", ">");
		return returnvalue;
	}

	/**
	 * 对象转XML报文（无格式输出）
	 * 
	 * @param obj
	 * @param alias
	 * @return
	 */
	public static String ObjectToXmlNoFormat(Object obj,HashMap<String, java.lang.Class> alias) {
		String returnvalue = "";
		XStream xstream = new XStream(new DomDriver());
		if (alias != null) {
			for (String key : alias.keySet()) {
				xstream.alias(key, alias.get(key));
			}
		}
		Writer writer = new StringWriter();
		xstream.marshal(obj, new CompactWriter(writer));
		returnvalue = writer.toString();
		return returnvalue;
	}

	/**
	 * 对象转XML报文（无格式输出）
	 * 
	 * @param obj
	 * @param alias
	 * @return
	 */
	public static String ObjectToXmlNoFormat(Object obj,HashMap<String, java.lang.Class> alias,HashMap<String, java.lang.Class> useAttribute) {
		String returnvalue = "";
		XStream xstream = new XStream(new DomDriver());
		if (alias != null) {
			for (String key : alias.keySet()) {
				xstream.alias(key, alias.get(key));
			}
		}
		if (useAttribute != null) {
			for (String key : useAttribute.keySet()) {
				xstream.useAttributeFor(useAttribute.get(key), key);
			}
		}

		Writer writer = new StringWriter();
		xstream.marshal(obj, new CompactWriter(writer));
		returnvalue = writer.toString();
		return returnvalue;
	}

	/**
	 * XMl转对象
	 * 
	 * @param xml
	 * @param cls
	 *            目标类Class
	 * @return
	 */
	public static Object XmlToObject(String xml,HashMap<String, java.lang.Class> alias) {
		Object obj = null;
		XStream xstream = new XStream(new DomDriver());
		// 忽略未知字段
		xstream.ignoreUnknownElements();
		// 添加字参数替换
		if (alias != null) {
			for (String key : alias.keySet()) {
				xstream.alias(key, alias.get(key));
			}
		}
		obj = xstream.fromXML(xml);
		return obj;
	}

	/**
	 * XMl转对象
	 * 
	 * @param xml
	 * @param class_name
	 * @param class_info
	 * @return
	 */
	public static Object XmlToObject(String xml, String class_name,java.lang.Class class_info) {
		Object obj = null;
		XStream xstream = new XStream(new DomDriver());
		// 忽略未知字段
		xstream.ignoreUnknownElements();
		xstream.alias(class_name, class_info);
		obj = xstream.fromXML(xml);
		return obj;
	}

	/**
	 * XML字符串转为Map
	 * 
	 * @param xml
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> parseXml(String xml) throws Exception {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();

		StringReader sr = new StringReader(xml);
		InputSource is = new InputSource(sr);

		Document document = db.parse(is);

		Map<String, Object> result = new HashMap<String, Object>();

		NodeList list = document.getDocumentElement().getChildNodes();
		for (int i = 0; i < list.getLength(); i++) {
			Node item = list.item(i);
			if (item.getNodeType() == Node.ELEMENT_NODE) {
				result.put(item.getNodeName(), item.getTextContent().trim());
			}
		}
		return result;
	}

	/**
	 * Map转为XML字符串
	 * 
	 * @param map
	 * @return
	 */
	public static String toXml(Map<String, Object> map) {
		StringBuilder sb = new StringBuilder();
		sb.append("<xml>");
		for (String key : map.keySet()) {
			sb.append("<" + key + ">" + map.get(key) + "</" + key + ">");
		}
		sb.append("</xml>");
		return sb.toString();
	}
}